﻿using System;
using System.Collections.Generic;
using System.Linq;
using Eg.Core;
using NHibernate;
using NHibernate.Criterion;

namespace QueryOverProjectionsAndAggregates {

  public class Queries {

    private readonly ISession _session;

    public Queries(ISession session) {
      if (session == null)
        throw new ArgumentNullException("session");
      _session = session;
    }

    public IEnumerable<NameAndPrice> GetMoviePriceList() {
      return _session.QueryOver<Movie>()
        .Select(m => m.Name, m => m.UnitPrice)
        .List<object[]>()
        // what follows is standard Linq to objects
        .Select(props =>
          new NameAndPrice {
            Name = (string)props[0],
            Price = (decimal)props[1]
          });
    }

    public decimal GetAverageMoviePrice() {
      var result = _session.QueryOver<Movie>()
        .Select(Projections.Avg<Movie>(m => m.UnitPrice))
        .SingleOrDefault<double>();

      // money - convert to decimal
      return Convert.ToDecimal(result);
    }

    public IEnumerable<NameAndPrice> GetAvgDirectorPrice() {
      return _session.QueryOver<Movie>()

          // group by and project the Director property and project the average UnitPrice
          .SelectList(list => list.SelectGroup(m => m.Director).SelectAvg(m => m.UnitPrice))
          
          .List<object[]>()
          .Select(props => new NameAndPrice() {
              Name = (string)props[0],
              Price = Convert.ToDecimal(props[1])
          });
    }

  }

}
